

#pragma once

#include "IniKeyValue.h"
#include "detail.h"


#pragma warning ( push )
#pragma warning ( disable : 4290 )


namespace ksini
{

	class IniNode
	{

		IniNode* m_root;

		std::string  m_name;
		std::string m_comment_line;

		std::vector<IniKeyValue> m_childrens_key_values;

		std::vector<IniNode>  m_child_nodes;

		/*
		IniNode(const IniNode& a)
		{
			throw std::runtime_error("wrong operation");
		}
		*/

	public:


		IniNode(const std::string&  m_name, const std::string& m_comment_line, IniNode* pRoot) throw(std::runtime_error);

		~IniNode()
		{

		}

		std::string get_node_name() const 
		{
			return m_name;
		}

		//void set_node_name(std::string& name)
		//{
		//	detail::
		//}

		//--------------------------------------------------------------

		bool hasRoot() const 
		{
			return m_root != NULL;
		}

		IniNode& getRoot() const throw (std::runtime_error)
		{
			if(!m_root) throw std::runtime_error("no has root");
			return *m_root;
		}

		std::string makeHierarhyName() const;

		bool hasChildsNodes() const 
		{
			return m_child_nodes.size() > 0;
		}

		size_t numChildsNodes() const 
		{
			return m_child_nodes.size();
		}

		IniNode& getChildNodeAt(size_t at) throw(std::runtime_error)
		{
			if( at > m_child_nodes.size()-1 ) throw std::runtime_error("bad index");
			return m_child_nodes.at(at);
		}

		IniNode& apendChildNode(const std::string& node_name, const std::string& node_comment) throw (std::runtime_error);

		bool eraseNode(const std::string& nodeName);

		//-------------------------------------------------------------

		bool hasChildsKeyValues() const 
		{
			return m_childrens_key_values.size() > 0;
		}

		size_t numChildsKeyValues() const 
		{
			return m_childrens_key_values.size();
		}

		IniKeyValue& getChildKeyValueAt(size_t at)
		{
			return m_childrens_key_values.at(at);
		}

		void apendChildKeyValue(IniKeyValue& kv)   throw(std::runtime_error);

		void apendChildKeyValue(const std::string& key, const std::string& value, const std::string& comment);

		bool eraseKey(const std::string& keyName);

		//-----------------------------------------------------------------

		void apendToStr(std::string& str, int& level) const  throw(std::runtime_error);

		void readFromStr(const std::string& str) throw(std::runtime_error);


		//-----------------------------------------------------------------

		void clearKeyValues()
		{
			m_childrens_key_values.clear();
		}

		void clearNodes()
		{
			m_child_nodes.clear();
		}


	};


}

#pragma warning ( pop )
